home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 590 / source / format.c next >
Encoding:
C/C++ Source or Header  |  1992-01-06  |  6.5 KB  |  255 lines

  1. /**********************************************************************
  2.  
  3.     Programm zum Formatieren von Disketten
  4.  
  5.  
  6.         von Wolfram Rösler
  7.              
  8.  
  9.       zum Aufruf als TTP oder von der Okami-Shell
  10.  
  11.  
  12. Datum      Ver.    Änderung
  13. 20.10.90  1.1    Volume Label (-l)
  14. 14.01.91  1.2    Schwerer Fehler beseitigt: &argv[i][2] statt argv[i][2]
  15. 24.05.91  1.3    Fehlerabfragen; -V: Versionsnummer
  16. 25.07.91  1.4    MSDOS-kompatibler Bootsektor
  17. 01.12.91  1.5    Anpassung an TurboC/PureC (Ansi-C)
  18.  
  19. **********************************************************************/
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <ctype.h>
  24. #include <tos.h>
  25.  
  26. #define PRGNAME     "format"    /* eigentlich: argv[0]            */
  27. #define VERSION        "1.5"    /* Versionsnummer            */
  28. #define FLAG_NOBOOT (-99)    /* Flag für keinen Bootsektor anlegen    */
  29. #define FLAG_NOFMT  (-987)    /* Flag für nur Bootsektor anlegen    */
  30. #define MAGIC        0x87654321L /* Magische Zahl, hexhexhex        */
  31. #define SECSIZE     512     /* Bytes pro Sektor            */
  32. #define FMTBUFSIZE  0x3000    /* Formatierpuffer            */
  33.  
  34. /* VT52-Steuercodes */
  35. #define C_SAVE        "\033j"
  36. #define C_RESTORE    "\033k"
  37.  
  38. char TError[]="!!! Error";
  39.  
  40. int YesOrNo(void)
  41. {
  42.   fputs("Do you really want to do that? (y or n) ",stdout);
  43.   fflush(stdout);
  44.   return tolower(getchar())!='y';
  45. }
  46.  
  47.  
  48. int Format(int devno,int spt,int Sides,int Tracks,int interlv,
  49.     unsigned virgin,long SerNo,int Exec,int Quiet,char *VolLbl)
  50. {
  51.   register int i,j;
  52.   register char *Buf;
  53.   int Erg;
  54.   
  55.   if (Exec!=FLAG_NOFMT)
  56.   {
  57.   
  58.     if (!Quiet)
  59.     {
  60.   
  61.       /* Parameter checken */
  62.       if (devno!=0 && devno!=1)
  63.       {   
  64.     printf("You are about to format drive %c.\n",(char)devno+'A');    
  65.     if (YesOrNo())
  66.       return 0;
  67.       }
  68.     
  69.       if (virgin!=0xe5e5)
  70.       {
  71.     printf("You are about to format with a virgin of 0x%x.\n",virgin);
  72.     if (YesOrNo())
  73.       return 0;
  74.       }
  75.     
  76.       /* Letzte Warnung */
  77.       printf(
  78.       "LAST CHANCE TO STOP:\nYou are about to format the disk in drive %c.\n",
  79.       (char)devno+'A');
  80.     
  81.       if (YesOrNo())
  82.         return 0;
  83.     
  84.     } /* if (!Quiet) */
  85.       
  86.     /* Los gehts */
  87.     
  88.     /* Speicher für Rückgabewert */
  89.     Buf=calloc(FMTBUFSIZE,sizeof(int));
  90.     if (Buf==NULL)
  91.     {
  92.       fprintf(stderr,"%s: Out of memory (need %d bytes)\n",PRGNAME,
  93.                         FMTBUFSIZE*sizeof(int));
  94.       return 1;
  95.     }
  96.     
  97.     /* *** FORMATIEREN *** */
  98.     
  99.     printf("Formatting disk %c, %d side%s, %d tracks, %d sec/track\n%s",
  100.         (char)devno+'A',Sides,Sides==1?"":"s",Tracks,spt,C_SAVE);
  101.  
  102.     for (i=Tracks-1;i>=0;i--)
  103.       for (j=0;j<Sides;j++)
  104.       {
  105.     printf("%s%sSide %d Track %d  ",C_RESTORE,C_SAVE,j,i);
  106.     fflush(stdout);
  107.     Erg=Flopfmt((int *)Buf,0L,devno,spt,i,j,interlv,MAGIC,
  108.                             i>1 ? virgin : 0);
  109.     if (Erg!=0)
  110.     {
  111.       fprintf(stderr,"\n%s %d on side %d, track %d\n",TError,Erg,j,i);
  112.       free(Buf);
  113.       return 1;
  114.     }
  115.       }
  116.  
  117.     free(Buf);
  118.     fputs(C_RESTORE,stdout);
  119.  
  120.   } /* if (Formatieren) */ 
  121.  
  122.   /* *** BOOTSEKTOR *** */
  123.   
  124.   if (Exec!=FLAG_NOBOOT)
  125.   {
  126.     printf("Creating %sexecutable boot sector",Exec ? "" : "non-");
  127.     fflush(stdout);
  128.     Buf=malloc(SECSIZE);
  129.     if (Buf==0)
  130.     {
  131.       fprintf(stderr,"\n%s: Out of memory (need %d bytes)\n",PRGNAME,
  132.                                 SECSIZE);
  133.       return 1;
  134.     }
  135.     Protobt(Buf,SerNo,(Sides-1)+(((Tracks/40)-1)<<1),Exec);
  136.     /* MSDOS-kompatibel */
  137.     Buf[0]=0xeb;
  138.     Buf[1]=0x34;
  139.     Buf[2]=0x90;
  140.     Erg=Flopwr(Buf,0L,devno,1,0,0,1);
  141.     free(Buf);
  142.     if (Erg!=0)
  143.     {
  144.       fprintf(stderr,"\n%s %d writing bootsector\n",TError,Erg);
  145.       return 1;
  146.     }
  147.   }
  148.  
  149.   fputc('\n',stdout);
  150.  
  151.   /* Diskettenname erzeugen */
  152.   if (VolLbl!=NULL && *VolLbl!='\0')
  153.   {
  154.     int Fd;
  155.     char Path[80+1];
  156.  
  157.     printf("Creating volume label");
  158.     fflush(stdout);
  159.     sprintf(Path,"%c:\\%s",devno+'A',VolLbl);
  160.     Fd = Fcreate(Path,1<<3);
  161.     if (Fd<0)
  162.       fprintf(stderr,"\n\t%s %d creating volume label\n",TError,Erg);
  163.     else
  164.       Fclose(Fd);
  165.     fputc('\n',stdout);
  166.   }
  167.   return 0;
  168. }
  169.  
  170. void Usage(char *PrgName)
  171. {
  172.   fprintf(stderr,
  173.    "Usage: %s [-V]|[-s(Sec/Trk)] [-t(Trk/Dsk)] [-1] [-i(interlv)] \\\n%s",PrgName,
  174.    "       [-v(virgin)] [-n(SerNo)] [-(N|B)] [-x] [-q] [-l(VolLbl)] [Drive]");
  175.   fprintf(stderr,"\nDefaults: -s9 -t80 -i1 -v0xE5E5 A:\n\n");
  176.   fprintf(stderr,"-1: Format Single Sided\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  177.          "-N: No Boot Sector",
  178.          "-B: Boot Sector only",
  179.          "-x: Executable Boot Sector",
  180.          "-q: No security requests",
  181.          "-l: Volume Label (default: none)",
  182.          "-V: just print version number",
  183.          "Drive: A or B (floppy disk drives only, no hard disks!)");
  184. }
  185.  
  186. int main(int argc,char *argv[])
  187. {
  188.   int    devno    = 0;        /* Laufwerksnummer: 0 A:, 1 B:        */
  189.   int    spt    = 9;        /* Sektoren pro Track            */
  190.   int    Sides    = 2;        /* Anzahl Seiten (1/2)            */
  191.   int    Tracks    = 80;         /* Anzahl Tracks            */
  192.   int    interlv    = 1;        /* Interleave-Faktor            */
  193.   unsigned virgin = 0xe5e5;    /* Virgin-Wort für Sektoren        */
  194.   long    SerNo    = 0x01000001L;    /* Seriennummer für Bootsektor        */
  195.   int    Exec    = 0;        /* Bootsektor ausführbar        */
  196.   int    Quiet    = 0;        /* Flag Sicherheitsabfragen: 0 ja,1 nein*/
  197.   char *VolLbl    = NULL;        /* Diskettenname oder NULL        */
  198.   int i;
  199.   
  200.   if (argc==1)
  201.     return Format(devno,spt,Sides,Tracks,interlv,virgin,SerNo,Exec,Quiet,VolLbl);
  202.   
  203.   /* Parameter scannen */
  204.   for (i=1;i<argc;i++)
  205.   {
  206.     if (argv[i][0]=='-')        /* Flag */
  207.       switch(argv[i][1])
  208.       {
  209.         case 'V':            /* Versionsnummer    */
  210.       puts("Okami Format " VERSION);
  211.       puts("compiled " __DATE__ " " __TIME__);
  212.       exit(0);
  213.     case 's':            /* Sektoren pro Track    */
  214.       spt=atoi(&argv[i][2]);
  215.       break;
  216.     case 't':            /* Tracks pro Disk    */
  217.       Tracks=atoi(&argv[i][2]); 
  218.       break;
  219.     case '1':            /* Einseitig        */
  220.       Sides=1;
  221.       break;
  222.     case 'i':            /* Interleaf-Faktor    */
  223.       interlv=atoi(&argv[i][2]);
  224.       break;
  225.     case 'v':            /* Virgin-Wort        */
  226.       virgin=(unsigned)atoi(&argv[i][2]);
  227.       break;
  228.     case 'n':            /* Seriennummer     */
  229.       SerNo=atol(&argv[i][2]);
  230.       break;
  231.     case 'N':            /* kein Bootsektor    */
  232.       Exec=FLAG_NOBOOT;
  233.       break;
  234.     case 'B':            /* nur Bootsektor    */
  235.       Exec=FLAG_NOFMT;
  236.       break;
  237.     case 'x':            /* Bootsektor ausführbar*/
  238.       Exec=1;
  239.       break;
  240.     case 'q':            /* keine Sicherheitsabfragen */
  241.       Quiet=1;
  242.       break;
  243.     case 'l':            /* Diskettenname    */
  244.       VolLbl= &(argv[i][2]);
  245.       break;
  246.     default:            /* Falsches Flag    */
  247.       Usage(PRGNAME);
  248.       return 1;
  249.       }
  250.     else                /* Laufwerksnummer    */
  251.       devno=tolower(argv[i][0])-'a';
  252.   }
  253.  
  254.   return Format(devno,spt,Sides,Tracks,interlv,virgin,SerNo,Exec,Quiet,VolLbl);
  255. }